package com.inexas.cu.stratus;

import static org.junit.Assert.*;
import java.util.*;
import org.junit.*;

public class BuildTestMockBigtable {
	private final static int YOUNG = 7;
	private final static int OLD = 23;
	private final static String YOUNG_MAN_NAME = "Andy";
	private final static String OLD_MAN_NAME = "Bob";
	private Stratus bt;
	private TestEntity oldMan, youngMan;

	@Before
	public void setup() {
		bt = new MockStratus();
		
		youngMan = new TestEntity(YOUNG_MAN_NAME, YOUNG);
		bt.create(youngMan);

		oldMan = new TestEntity(OLD_MAN_NAME, OLD);
		bt.create(oldMan);
	}

	@Test
	public void ensureSetupIsOk() {
		assertNotNull(oldMan);
		assertNotNull(oldMan.getIdent());
		assertNotNull(youngMan);
		assertNotNull(youngMan.getIdent());
	}

	@Test
	public void findByIdent() {
		final TestEntity p1 = bt.findByIdent(TestEntity.class, oldMan.getIdent());
		assert p1.getIdent() != null;
		assert p1.getAge() == OLD;
    }

	@Test
	public void findAll() {
		final Iterator<TestEntity> all = bt.findAll(TestEntity.class);
		int count = 0;
		while(all.hasNext()) {
			all.next();
			count++;
		}
		assert count == 2;
    }

	@Test
	public void findBy() {
		final TestEntity te = bt.findBy(TestEntity.class, "name:'" + YOUNG_MAN_NAME + "'");
		assert te.getAge() == YOUNG;
	}
	
	@SuppressWarnings("unchecked")
	@Test
	public void findAllBy() {
		// WHERE...
		final List<TestEntity> andies = (List<TestEntity>)bt.findAllBy( //
		        TestEntity.class, //
		        "name:'" + YOUNG_MAN_NAME + "'");
		assert andies.size() == 1;
		for(final TestEntity p : andies) {
			assert p.getName().equals(YOUNG_MAN_NAME) :	//
				"Expected: '" + YOUNG_MAN_NAME + "' got: '" + p.getName() + '\'';
		}
		final List<TestEntity> adults =  (List<TestEntity>)bt.findAllBy(TestEntity.class, "age>18");
		assert adults.size() > 0;
		for(final TestEntity p : adults) {
			assert p.getName().equals(OLD_MAN_NAME);
		}
		// ORDER BY...
		final List<TestEntity> youngestFirst = (List<TestEntity>)bt.findAllBy(TestEntity.class, "age");
		assert youngestFirst.size() > 0;
		assert youngestFirst.get(0).getAge() == YOUNG;
		final List<TestEntity> youngestFirst1 = (List<TestEntity>)bt.findAllBy(TestEntity.class, "age+");
		assert youngestFirst1.size() > 0;
		assert youngestFirst1.get(0).getAge() == YOUNG;
		final List<TestEntity> oldestFirst = (List<TestEntity>)bt.findAllBy(TestEntity.class, "age-");
		assert oldestFirst.size() > 0;
		assert oldestFirst.get(0).getAge() == OLD;
	}

	@Test
	public void update() {
		// void update(BigtableEntity entity) throws NoSuchEntityException;
		final int age = oldMan.getAge();
		assert bt.findByIdent(TestEntity.class, oldMan.getIdent()).getAge() == age;
		
		oldMan.setAge(age + 1);
		bt.update(oldMan);
		assert bt.findByIdent(TestEntity.class, oldMan.getIdent()).getAge() == age + 1;
		
		oldMan.setAge(age);
		bt.update(oldMan);
		assert bt.findByIdent(TestEntity.class, oldMan.getIdent()).getAge() == age;
    }

	@Test
	public void delete() {
		// void delete(BigtableEntity entity) throws NoSuchEntityException;
		bt.delete(oldMan);
		assert bt.findBy(TestEntity.class, "name:'" + OLD_MAN_NAME + '\'') == null;
		// Put things back the way they were...
		oldMan = new TestEntity(OLD_MAN_NAME, OLD);
		bt.create(oldMan);
    }

	@Test
	public void deleteAll() {
		// void deleteAll(Class<? extends BigtableEntity> class1);
		bt.deleteAll(TestEntity.class);
		assert bt.findAll(TestEntity.class).hasNext() == false;
    }

}
